package com.huaao.micropolice.core.service.system.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.druid.util.StringUtils;
import com.huaao.micropolice.core.model.system.Area;
import com.huaao.micropolice.core.model.system.Dept;
import com.huaao.micropolice.core.repository.content.SubjectDao;
import com.huaao.micropolice.core.repository.system.DeptDao;
import com.huaao.micropolice.core.repository.system.JobsDao;
import com.huaao.micropolice.core.repository.system.RoleDao;
import com.huaao.micropolice.core.repository.system.UserDao;
import com.huaao.micropolice.core.service.system.DeptService;

@Service
@Transactional
public class DeptServiceImpl implements DeptService{
	
	@Autowired
	private DeptDao deptDao;
	@Autowired
	private RoleDao roleDao;
	
	@Autowired
	private UserDao userDao;
	@Autowired
	private JobsDao jobsDao;
	@Autowired
	private SubjectDao subjectDao;
	
	@Override
	public String save(Dept obj) {
		Dept parent = (Dept) deptDao.load(Dept.class, obj.getParentId());
		obj.setLeve(parent.getLeve()+1);
		obj.setIsLeaf(Dept.LEAF_YES);
		parent.setIsLeaf(Dept.LEAF_NO);
		deptDao.save(parent);
		return deptDao.save(obj);
	}

	@Override
	public List<Dept> findByDeptname(String name) {
		return null;
	}

	@Override
	public List<Dept> findByDeptParentId(String id) {
		// TODO Auto-generated method stub
		if(StringUtils.isEmpty(id)){
			List<Dept> list = new ArrayList();
			list.add((Dept) deptDao.load(Dept.class,"0"));
			list.addAll(deptDao.findByDeptParentId("0"));
			return list;
		}else{
			return deptDao.findByDeptParentId(id);
		}
		
	}

	@Override
	public void update(Dept obj) {
		Dept no = (Dept)deptDao.load(Dept.class, obj.getId());
		try {
			if(no.getParentId().equals(obj.getParentId())){
				no.setName(obj.getName());
				no.setCode(obj.getCode());
				no.setAreaId(obj.getAreaId());
				deptDao.update(no);
			}else{
				//检查原来父节点是否变为子节点
				Dept oldParent = (Dept)deptDao.get(Dept.class, no.getParentId());
				no.setName(obj.getName());
				no.setCode(obj.getCode());
				no.setAreaId(obj.getAreaId());
				no.setParentId(obj.getParentId());
				deptDao.update(no);
				if(oldParent.getChildren().size() <= 1){
					oldParent.setIsLeaf(Dept.LEAF_YES);
					deptDao.update(oldParent);
				}
				
				//检查是否需要更新LEVEL。如需要则更改其以下节点的LEVEL
				Dept newParent = (Dept)deptDao.get(Dept.class, obj.getParentId());
				if(oldParent.getLeve() != newParent.getLeve()){
					this.updateLevel(no);
				}
				//新的父节点需要更新is_leaf
				if(Dept.LEAF_YES.equals(newParent.getIsLeaf()) ){
					newParent.setIsLeaf(Dept.LEAF_NO);
					deptDao.update(newParent);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		 
	}

	private void updateLevel(Dept dept){
		Dept p = (Dept)deptDao.load(Dept.class, dept.getParentId());
		dept.setLeve(p.getLeve()+1);
		deptDao.update(dept);
		for(Dept item : dept.getChildren()){
			this.updateLevel(item);
		}
	}
	
	@Override
	public void del(String id) throws Exception {
		Dept obj = deptDao.load(id);
		delDept(obj);
		//检查父节点是否需要更新is_leaf
		Dept p = deptDao.load(obj.getParentId());
		if(p.getChildren().size() <= 1){
			p.setIsLeaf(Dept.LEAF_YES);
			deptDao.update(p);
		}
	}
	
	private void delDept(Dept obj) throws Exception{
		Set<Dept> list = obj.getChildren();
		for(Dept item : list){
			delDept(item);
		}
		if( !userDao.findByDeptId(obj.getId()).isEmpty() ){
			throw new Exception("["+obj.getName()+"] 存在关联人员，无法删除");
		}
		if( !jobsDao.findByDeptId(obj.getId()).isEmpty() ){
			throw new Exception("["+obj.getName()+"] 存在关联人员类型，无法删除");
		}
		if( !roleDao.findByDept(obj.getId()).isEmpty()){
			throw new Exception("["+obj.getName()+"] 存在关联角色，无法删除");
		}
		if( !subjectDao.findByDept(obj.getId()).isEmpty()){
			throw new Exception("["+obj.getName()+"] 存在关联栏目，无法删除");
		}
		deptDao.deleteById(Dept.class, obj.getId());
	}

	@Override
	public List<Dept> findAll() {
		List<Dept> list = deptDao.findAll();
		List<Dept> destList = new ArrayList<Dept>();
		sortList(destList,list,null);
		return destList;
	}
	
	private void sortList(List<Dept> destList, List<Dept> sourceList, String parentId) {
		for (int i=0; i<sourceList.size(); i++){
			Dept e = sourceList.get(i);
			if((e.getParent() == null && parentId==null) || (e.getParent() != null && e.getParent().getId().equals(parentId))){
				if(!destList.contains(e)){
					destList.add(e);
				}
				sortList(destList,sourceList,e.getId());
			}
		}
	} 
}
